package operation.commom.system;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日付操作のユーティリティクラス
 */
public class DateProcessing {

    /** yyyyMMdd */
    public static final String DATEFORMAT01 = "yyyyMMdd";
    /** MM/dd HH:mm:ss.SSS */
    public static final String DATEFORMAT02 = "MM/dd HH:mm:ss.SSS";
    /** yyyy/MM/dd HH:mm:ss */
    public static final String DATEFORMAT03 = "yyyy/MM/dd HH:mm:ss";
    /** HH:mm:ss */
    public static final String DATEFORMAT04 = "HH:mm:ss";
    /** yyyyMMddHHmmss */
    public static final String DATEFORMAT05 = "yyyyMMddHHmmss";
    /** yyyy/MM/dd */
    public static final String DATEFORMAT06 = "yyyy/MM/dd";
    /** yyyy/MM/dd,HH:mm:ss */
    public static final String DATEFORMAT07 = "yyyy/MM/dd,HH:mm:ss";
    /** yyyyMMddHHmm */
    public static final String DATEFORMAT08 = "yyyyMMddHHmm";
    /** yyyy-MM-dd HH:mm:ss */
    public static final String DATEFORMAT09 = "yyyy-MM-dd HH:mm:ss";
    /** yyyy/MM/dd */
    public static final String DATEFORMAT10 = "yyyy-MM-dd";

    /**
     * Date型日付を文字列に変換する。
     *
     * @param date
     * @param formatString 変換フォーマット
     * @return
     */
    public static String getStringByDateWithFormat(Date date, String formatString) {
        SimpleDateFormat format = new SimpleDateFormat(formatString);
        return format.format(date);
    }

    /**
     *
     * 日付文字列をfarmat型に解析しDateを取得
     *
     * @param dateString
     * @param formatString
     * @return
     */
    public static Date getDateByStringWithFormat(String dateString, String formatString) {
        Date result = null;

        SimpleDateFormat format = new SimpleDateFormat(formatString);
        try {
            result = format.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 現在の日付をフォーマット指定で取得する。<BR>
     *
     * @return nowDate 現在の日付(String)
     */
    public static String getToday(String format) {
        SimpleDateFormat sdf = new SimpleDateFormat();
        Date date = new Date();
        sdf.setLenient(true);
        sdf.applyPattern(format);
        String nowDate = sdf.format(date);
        return nowDate;
    }

    /**
     * 指定された日付（年月日）に指定された日数を加算或いは減算したDateオブジェクトを返す。 指定された日付が実在しない場合または日数の加減算ができなかった場合はnullを返す。
     *
     * @param date 加減算の基準となる日付
     * @param additionalDay 加算する場合はプラスの値、減算する場合はマイナスの値
     * @return 加(減)算後のDateオブジェクト
     */
    public static Date addDay(Date date, int additionalDay) {
        Date result = null;
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(date.getTime());
            calendar.add(Calendar.DATE, additionalDay);
            result = calendar.getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 指定された日付に指定された時数を加算或いは減算したDateオブジェクトを返す。 指定された日付が実在しない場合または時数の加減算ができなかった場合はnullを返す。
     *
     * @param date 加減算の基準となる日付
     * @param additionalHour 加算する場合はプラスの値、減算する場合はマイナスの値
     * @return 加(減)算後のDateオブジェクト
     */
    public static Date addHour(Date date, int additionalHour) {
        Date result = null;
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(date.getTime());
            calendar.add(Calendar.HOUR, additionalHour);
            result = calendar.getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static Date addMinute(Date date, int additionalMinute) {
        Date result = null;
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(date.getTime());
            calendar.add(Calendar.MINUTE, additionalMinute);
            result = calendar.getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 指定された月に指定された時数を加算或いは減算したDateオブジェクトを返す。 指定された日付が実在しない場合または時数の加減算ができなかった場合はnullを返す。
     *
     * @param date 加減算の基準となる日付
     * @param additionalMonth 加算する場合はプラスの値、減算する場合はマイナスの値
     * @return 加(減)算後のDateオブジェクト
     */
    public static Date addMonth(Date date, int additionalMonth) {
        Date result = null;
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(date.getTime());
            calendar.add(Calendar.MONTH, additionalMonth);
            result = calendar.getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /***
     * 计算两个日期之差
     *
     * @param dateStart
     * @param dateEnd
     * @param calendarType
     * @return
     */
    public static int getIntervalDays(Date dateStart, Date dateEnd, int calendarType) {
        int tempVaule = 1;
        switch (calendarType) {
            case Calendar.MONTH:
                tempVaule *= 30;
            case Calendar.DATE:
                tempVaule *= 24;
            case Calendar.HOUR:
                tempVaule *= 60;
            case Calendar.MINUTE:
                tempVaule *= 60;
            default:
                tempVaule *= 1000;
        }
        return (int) ((dateEnd.getTime() - dateStart.getTime()) / tempVaule);
    }

    /***
     * 判断字符串是否是指定格式
     *
     * @param str
     * @param formatString
     * @return
     */
    public static boolean isValidDate(String str, String formatString) {
        boolean convertResult=true;
        SimpleDateFormat format = new SimpleDateFormat(formatString);
        try {
            // 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期，比如2007-02-29会被接受，并转换成2007-03-01
           format.setLenient(false);
           format.parse(str);
         } catch (ParseException e) {
            convertResult = false;  //格式不正确
        }
        return convertResult;
    }

    /**
     * 时间字符串转换int格式
     *
     * @param timeString
     * @param type
     * @return
     */
    public static int getTimeStringToInt(String timeString, int type) {
        int timeInt;
        // type为0时取日期8位到日，否则取10位到时
        if (type == 0) {
            timeInt = Integer.parseInt(timeString.replaceAll("[^0-9]", "").substring(0, 8));
        } else {
            timeInt = Integer.parseInt(timeString.replaceAll("[^0-9]", "").substring(0, 10));
        }
        return timeInt;
    }

    /**
     * 日期字符串转换int格式
     * @param timeDate
     * @param type
     * @return
     */
    public static int getTimeDateToInt(Date timeDate, int type) {
        // Date转字符串
        String timeString = getStringByDateWithFormat(timeDate, DATEFORMAT09);
        // 调用时间字符串转换int，type为0时取日期8位到日，否则取10位到时
        int timeInt = getTimeStringToInt(timeString, type);
        return timeInt;
    }
}
